#ifndef __CONFIG_H__
#define __CONFIG_H__

#include <assert.h>
#include <math.h>
#include <stdarg.h>

#define SQEMODE -1
#define INT int
#define DOUBLE double
#define BOOL bool

#define MPI_USE 1
#if MPI_USE
#include "mpi.h"
#define DEFAULT_COMM MPI_COMM_WORLD
#define PRINT_RANK 0
#define ROOT_RANK 0
#elif
#define DEFAULT_COMM -1
#endif

#define GetName(x) #x

///////////////////////////////////////////////////////////////////////////
/*                        external package config                        */
///////////////////////////////////////////////////////////////////////////

#define MKL_USE 1
#define BLAS_USE 1
#define LAPACK_USE 1
///////////////////////////////////////////////////////////////////////////
#ifndef MKL_USE

#define BLAS_WRAPPER(x) x ## _
#if defined(BLAS_USE)
#define dscal BLAS_WRAPPER(dscal)
extern void dscal(int *n, double *alpha, double *x, int *incx);
#define daxpy BLAS_WRAPPER(daxpy)
extern void daxpy(int *n, double *alpha, double *x, int *incx, double *y, int *incy);
#endif

#else

#include <mkl.h>
#include <mkl_spblas.h>

#endif
///////////////////////////////////////////////////////////////////////////
#define PETSC_USE 1
#if defined(PETSC_USE)
#include "petscksp.h"
#include "petscao.h"
#include "petscmat.h"
#include "matimpl.h"
#include "mpiaij.h"
#else
#define RaisePetscError(FUNCTION_NAME)                        \
    do                                                        \
    {                                                         \
        OpenPFEM_Print("%s requires PETSc\n", FUNCTION_NAME); \
        assert(0);                                            \
    } while (0)
#endif

#define SLEPC_USE 1
// #if defined(PETSC_USE)
#include "slepc.h"
#include "slepceps.h"
#include "epsimpl.h"
// #else
#define RaiseSlepcError(FUNCTION_NAME)                        \
    do                                                        \
    {                                                         \
        OpenPFEM_Print("%s requires SLEPc\n", FUNCTION_NAME); \
        assert(0);                                            \
    } while (0)
// #endif

// #define PASE_USE 1
#if PASE_USE && SLEPC_USE && PETSC_USE
#include "pase.h"
#else
#define RaisePASEError(FUNCTION_NAME)                        \
    do                                                        \
    {                                                         \
        OpenPFEM_Print("%s requires PASE\n", FUNCTION_NAME); \
        assert(0);                                            \
    } while (0)
#endif

#endif
